package cn.liutao.order.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.liutao.auth.entity.po.User;
import cn.liutao.auth.mapper.UserMapper;
import cn.liutao.auth.service.AuthService;
import cn.liutao.common.enums.CommonEnum;
import cn.liutao.common.enums.OrderEnum;
import cn.liutao.common.enums.PayEnum;
import cn.liutao.common.exception.BadRequestException;
import cn.liutao.common.exception.OrderException;
import cn.liutao.common.utils.RedisUtils;
import cn.liutao.common.utils.ServletUtils;
import cn.liutao.dish.entity.po.DiningTable;
import cn.liutao.dish.entity.po.Dish;
import cn.liutao.dish.entity.po.Taste;
import cn.liutao.dish.mapper.DiningTableMapper;
import cn.liutao.dish.mapper.DishMapper;
import cn.liutao.dish.mapper.TasteMapper;
import cn.liutao.order.entity.dto.OrderCreateResultDto;
import cn.liutao.order.entity.dto.OrderPriceDto;
import cn.liutao.order.entity.param.*;
import cn.liutao.order.entity.po.*;
import cn.liutao.order.entity.vo.CartVo;
import cn.liutao.order.entity.vo.OrderVo;
import cn.liutao.order.mapper.*;
import com.alibaba.fastjson2.JSONObject;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.core.relation.RelationManager;
import com.mybatisflex.core.row.Db;
import com.mybatisflex.core.transaction.TransactionException;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import static cn.liutao.dish.entity.po.table.DiningTableTableDef.DINING_TABLE;
import static cn.liutao.order.entity.po.table.CartTableDef.CART;
import static cn.liutao.order.entity.po.table.OrderBillTableDef.ORDER_BILL;
import static cn.liutao.order.entity.po.table.OrderCartRelationTableDef.ORDER_CART_RELATION;
import static cn.liutao.order.entity.po.table.OrderTableDef.ORDER;
import static cn.liutao.order.entity.po.table.PayBillTableDef.PAY_BILL;

/**
 * 服务层实现。
 *
 * @author liutao
 * @since 2023-11-02
 */
public class OrderService {
    private static volatile OrderService instance;
    private OrderMapper orderMapper;
    private CartMapper cartMapper;
    private OrderCartRelationMapper relationMapper;
    private OrderBillMapper orderBillMapper;
    private UserMapper userMapper;
    private DiningTableMapper tableMapper;
    private DishMapper dishMapper;
    private TasteMapper tasteMapper;
    private CartService cartService;
    private AuthService authService;
    private PayBillMapper payBillMapper;

    private OrderService() {
        orderMapper = ServletUtils.getMapper(OrderMapper.class);
        relationMapper = ServletUtils.getMapper(OrderCartRelationMapper.class);
        cartMapper = ServletUtils.getMapper(CartMapper.class);
        orderBillMapper = ServletUtils.getMapper(OrderBillMapper.class);
        userMapper = ServletUtils.getMapper(UserMapper.class);
        tableMapper = ServletUtils.getMapper(DiningTableMapper.class);
        tasteMapper = ServletUtils.getMapper(TasteMapper.class);
        dishMapper = ServletUtils.getMapper(DishMapper.class);
        payBillMapper = ServletUtils.getMapper(PayBillMapper.class);
        cartService = CartService.getInstance();
        authService = AuthService.getInstance();
    }

    static {
        if (instance == null) {
            synchronized (OrderService.class) {
                if (instance == null) {
                    instance = new OrderService();
                }
            }
        }
    }

    public static OrderService getInstance() {
        return instance;
    }

    /**
     * 创建订单
     * @param addParam
     */
    public OrderCreateResultDto createOrder(OrderCreateParam addParam) {
        OrderCreateResultDto resultDto = new OrderCreateResultDto();
        Order order = new Order();
        BeanUtil.copyProperties(addParam, order, "itemList");
        //计算餐桌人数
        DiningTable table = tableMapper.selectOneByQuery(QueryWrapper.create().where(DINING_TABLE.ID.eq(order.getTableId())).and(DINING_TABLE.STATUS.eq(CommonEnum.STATUS_ON.getIntValue())));
        if (table==null){
            throw new OrderException("所选餐桌不存在");
        }
        Integer peopleQuantity = order.getPeopleQuantity() == null ? 0 : order.getPeopleQuantity();
        Integer totalQuantity = table.getTotalQuantity() == null ? 0 : table.getTotalQuantity();
        Integer usedQuantity = table.getUsedQuantity() == null ? 0 : table.getUsedQuantity();
        Integer remainQuantity = totalQuantity-usedQuantity;
        if (totalQuantity.compareTo(peopleQuantity)<0){
            throw new BadRequestException(table.getName()+"共有位置：【"+totalQuantity+"】不足需求位置：【"+order.getPeopleQuantity()+"】");
        }
        if (remainQuantity==0|| remainQuantity.compareTo(peopleQuantity)<0){
            throw new BadRequestException(table.getName()+"剩余位置：【"+remainQuantity+"】不足需求位置：【"+order.getPeopleQuantity()+"】");
        }
        //开启事务
        Db.tx(() -> {
            //增加餐桌使用人数
            table.setUsedQuantity(peopleQuantity+usedQuantity);
            tableMapper.update(table);
            //计算价格
            List<CartVo> cartList = addParam.getItemList();
            OrderPriceDto priceDto = this.getNowPrice(cartList);
            order.setTotalPrice(priceDto.getPrice());
            //生成订单号
            String format = new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date());
            String orderNo = "ORDER" + format;
            order.setOrderNo(orderNo);
            LocalDateTime now = LocalDateTime.now();
            order.setCreateTime(now);
            order.setStatus(OrderEnum.ORDER_STATUS_NO_PAY.getIntValue());
            order.setPayTime(null);
            order.setTotalQuantity(priceDto.getQuantity());
            //创建订单
            orderMapper.insert(order);
            //创建订单关联数据
            List<OrderCartRelation> relationList = cartList.stream().map(cart -> {
                OrderCartRelation relation = new OrderCartRelation();
                relation.setOrderId(order.getId());
                relation.setCartId(cart.getId());
                relation.setPrice(cart.getPrice());
                return relation;
            }).collect(Collectors.toList());
            relationMapper.insertBatch(relationList);
            //创建订单记录
            List<Integer> cartIds = relationList.stream().map(OrderCartRelation::getCartId).collect(Collectors.toList());
            String ids = StrUtil.join(",", cartIds);
            OrderBill orderBill = new OrderBill();
            orderBill.setOrderNo(orderNo);
            orderBill.setCreateTime(now);
            orderBill.setUserId(order.getUserId());
            orderBill.setCartId(ids);
            orderBill.setTotalQuantity(priceDto.getQuantity());
            orderBill.setStatus(OrderEnum.ORDER_STATUS_NO_PAY.getIntValue());
            //在购物车记录中保存下单时的购物车信息
            String cartListStr = JSONObject.toJSONString(cartList);
            orderBill.setCartInfo(cartListStr);
            orderBillMapper.insert(orderBill);
            //修改关联购物车状态为已下单
            Cart cartDB = new Cart();
            cartDB.setStatus(OrderEnum.CART_STATUS_BUY.getIntValue());
            cartMapper.updateByQuery(cartDB,QueryWrapper.create().where(CART.ID.in(cartIds)));
            //订单缓存到redis中
            String orderString = JSONObject.toJSONString(order);
            RedisUtils.set(CommonEnum.ORDER_KEY.getValue() + orderNo, orderString, 60 * 30l);//30分钟过期时间

            //新增支付数据
            PayBill payBill = new PayBill();
            payBill.setOrderNo(orderNo);
            payBill.setUserId(addParam.getUserId());
            String payNo = new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date());
            payBill.setPayNo(payNo);
            payBill.setStatus(PayEnum.PAY_STATUS_NO_BUY.getIntValue());
            payBill.setType(PayEnum.PAY_TYPE_BUY.getIntValue());
            payBill.setTotalPrice(order.getTotalPrice());
            payBillMapper.insert(payBill);
            resultDto.setOrderNo(orderNo);
            resultDto.setPayNO(payNo);
            return true;
        });

        return resultDto;
    }

    /**
     * 分页查询
     *
     * @param queryParam
     * @return
     */
    public Page<OrderVo> selectList(OrderQueryParam queryParam) {
        QueryWrapper qw = QueryWrapper.create().from(ORDER)
                .where(ORDER.STATUS.eq(queryParam.getStatus()))
                .and(ORDER.USER_ID.eq(queryParam.getUserId()))
                .and(ORDER.PEOPLE_QUANTITY.eq(queryParam.getPeopleQuantity()))
                .and(ORDER.TABLE_ID.eq(queryParam.getTableId()))
                .and(ORDER.ORDER_NO.like(queryParam.getOrderNo()))
                .and(ORDER.PAY_TIME.between(queryParam.getPayTimeStart(), queryParam.getPayTimeEnd()))
                .and(ORDER.CREATE_TIME.between(queryParam.getCreateTimeStart(), queryParam.getCreateTimeEnd()))
                .orderBy(ORDER.CREATE_TIME, false);
//        RelationManager.setMaxDepth(2);
        RelationManager.addExtraConditionParam("dishStatus",CommonEnum.STATUS_ON.getIntValue());
        RelationManager.addExtraConditionParam("tasteStatus",CommonEnum.STATUS_ON.getIntValue());
        RelationManager.addExtraConditionParam("tableStatus",CommonEnum.STATUS_ON.getIntValue());
        Page<OrderVo> page = orderMapper.paginateWithRelationsAs(queryParam.getPageNum(), queryParam.getPageSize(), qw, OrderVo.class);
        page.getRecords().forEach(orderVo->{
            getOrderMsg(orderVo);
            cartService.genUnitPrice(orderVo.getItemList());
        });
        return page;
    }


    /**
     * 获取待出单订单当前的队列序号
     * @param orderVo
     */
    private void getOrderMsg(OrderVo orderVo) {
        if (OrderEnum.ORDER_STATUS_NO_SERVE.getIntValue().compareTo(orderVo.getStatus())==0){
            //获取当前队列的序号
            long count = orderMapper.selectCountByQuery(QueryWrapper.create()
                    .where(ORDER.ID.ne(orderVo.getId()))
                    .where(ORDER.STATUS.eq(OrderEnum.ORDER_STATUS_NO_SERVE.getIntValue()))
                    .where(ORDER.PAY_TIME.le(orderVo.getPayTime()))
                    .orderBy(ORDER.PAY_TIME, false));
            String msg;
            msg = "尊敬的小主，请耐心等待，您目前排在第"+(count+1)+"位";
            orderVo.setOrderMsg(msg);
        }
    }


    /**
     * 通过id查询
     * @param id
     * @return
     */
    public OrderVo selectById(Integer id) {
        RelationManager.addExtraConditionParam("dishStatus",CommonEnum.STATUS_ON.getIntValue());
        RelationManager.addExtraConditionParam("tasteStatus",CommonEnum.STATUS_ON.getIntValue());
        RelationManager.addExtraConditionParam("tableStatus",CommonEnum.STATUS_ON.getIntValue());
        OrderVo orderVo = orderMapper.selectOneWithRelationsByQueryAs(QueryWrapper.create().where(ORDER.ID.eq(id)), OrderVo.class);
        if (orderVo==null){
            throw new OrderException("订单不存在");
        }
        //获取订单信息
        getOrderMsg(orderVo);
        //设置单价
        cartService.genUnitPrice(orderVo.getItemList());
        return orderVo;
    }

    /**
     * 通过id查询
     * @param orderNo
     * @return
     */
    public OrderVo selectVoByNo(String orderNo) {
        RelationManager.addExtraConditionParam("dishStatus",CommonEnum.STATUS_ON.getIntValue());
        RelationManager.addExtraConditionParam("tasteStatus",CommonEnum.STATUS_ON.getIntValue());
        RelationManager.addExtraConditionParam("tableStatus",CommonEnum.STATUS_ON.getIntValue());
        OrderVo orderVo = orderMapper.selectOneWithRelationsByQueryAs(QueryWrapper.create().where(ORDER.ORDER_NO.eq(orderNo)), OrderVo.class);
        if (orderVo==null){
            throw new OrderException("订单不存在");
        }
        //获取订单信息
        getOrderMsg(orderVo);
        //设置单价
        cartService.genUnitPrice(orderVo.getItemList());
        return orderVo;
    }


    /**
     * 用于订单中的购物车列表中菜品的实时价格
     *
     * @param itemList 订单列表
     * @return 返回价格参数
     */
    protected OrderPriceDto getNowPrice(List<CartVo> itemList) {
        BigDecimal totalPrice = BigDecimal.ZERO;
        int tptalQuantity = 0;
        for (CartVo cartVo : itemList) {
            RelationManager.addExtraConditionParam("dishStatus",CommonEnum.STATUS_ON.getIntValue());
            RelationManager.addExtraConditionParam("tasteStatus",CommonEnum.STATUS_ON.getIntValue());
            CartVo cart = cartMapper.selectOneWithRelationsByIdAs(cartVo.getId(), CartVo.class);
            Dish dish=null;
            Taste taste=null;
            if (cart!=null){
                 dish = cart.getDish();
                 taste = cart.getTaste();
            }else{
                dish = dishMapper.selectOneById(cartVo.getDishId());
                taste = tasteMapper.selectOneById(cartVo.getId());
            }

            BigDecimal price = BigDecimal.ZERO;

            int quantity = 0;
            if (dish != null) {
                price=price.add(dish.getPrice() == null ? BigDecimal.ZERO : dish.getPrice());
            }
            if (taste != null) {
                price=price.add(taste.getPrice() == null ? BigDecimal.ZERO : taste.getPrice());
            }
            quantity = cart.getQuantity() == null ? 0 : cart.getQuantity();
            price = price.multiply(new BigDecimal(quantity));
            cartVo.setPrice(price);

            totalPrice = totalPrice.add(price);
            tptalQuantity += quantity;
        }
        return new OrderPriceDto(totalPrice, tptalQuantity);
    }

    /**
     * 订单支付
     * @param payParam 支付参数
     * @return 返回支付信息
     */
    public OrderCreateResultDto orderPay(Integer userId, OrderPayParam payParam) {
        OrderCreateResultDto resultDto = new OrderCreateResultDto();
        //判断密码是否正确
        boolean verifyPassword = authService.verifyPayPassword(userId, payParam.getPayPassword());
        if (!verifyPassword){
            throw new BadRequestException("支付密码错误");
        }
        String payNo = payParam.getPayNo();
        //查询支付记录
        PayBill payBill = payBillMapper.selectOneByQuery(QueryWrapper.create().where(PAY_BILL.PAY_NO.eq(payNo)));
        if (payBill==null){
            throw new BadRequestException("支付记录不存在");
        }
        //判断此支付记录是否可以支付
        if (payBill.getStatus().compareTo(PayEnum.PAY_STATUS_BUY_SUCCESS.getIntValue())==0){
            throw new BadRequestException("已支付，请勿重复支付");
        }
        String orderNo = payBill.getOrderNo();
        //获取redis中的订单信息，判断订单是否过期
        Order order = RedisUtils.get(CommonEnum.ORDER_KEY.getValue() + orderNo, Order.class);
            //过期
        if (order == null) {
            //将订单信息以及订单记录修改为已过期
            updateOrderStatus(orderNo, OrderEnum.ORDER_STATUS_OVERDUE.getIntValue());
            throw new BadRequestException("订单已过期");
        }
        try{
            Db.tx(()->{
                //未过期
                //判断用户是否余额充足
                User user = userMapper.selectOneById(userId);
                BigDecimal balance = user.getBalance()==null?BigDecimal.ZERO:user.getBalance();
                if (balance.compareTo(order.getTotalPrice())<0){
                    throw new BadRequestException("余额不足,请联系管理员充值");
                }
                //余额充足减少余额
                balance = balance.subtract(order.getTotalPrice());
                user.setBalance(balance);
                userMapper.update(user);
                //修改支付记录
                payBill.setType(PayEnum.PAY_TYPE_BUY.getIntValue());
                payBill.setMethod(PayEnum.PAY_METHOD_BALANCE.getIntValue());
                payBill.setStatus(PayEnum.PAY_STATUS_BUY_SUCCESS.getIntValue());
                payBill.setPayTime(LocalDateTime.now());
                payBillMapper.update(payBill);
                //修改订单信息
                order.setPayTime(LocalDateTime.now());
                order.setStatus(OrderEnum.ORDER_STATUS_NO_SERVE.getIntValue());
                orderMapper.update(order);
                //修改订单记录信息
                OrderBill orderBill = selectBillByNo(orderNo);
                orderBill.setPayTime(LocalDateTime.now());
                orderBill.setPayPrice(order.getTotalPrice());
                orderBill.setStatus(OrderEnum.ORDER_STATUS_NO_SERVE.getIntValue());
                orderBillMapper.update(orderBill);
                //删除缓存中的订单信息
                RedisUtils.remove(CommonEnum.ORDER_KEY.getValue()+orderNo);

                resultDto.setPayNO(payNo);
                resultDto.setOrderNo(orderNo);
                return true;
            });
        }catch (TransactionException e){
            e.printStackTrace();
            throw new BadRequestException(e.getMessage());
        }
        //开启统一事务管理
        return resultDto;
    }

    /**
     * 删除订单
     *
     * @param orderId 订单编号
     */
    public void removeById(Integer orderId) {
        //允许删除的两个状态集合
        List<Integer> statusList = Arrays.asList(OrderEnum.ORDER_STATUS_OVERDUE.getIntValue(),OrderEnum.ORDER_STATUS_FINISHED.getIntValue());
        QueryWrapper qw = QueryWrapper.create().where(ORDER.ID.eq(orderId)).and(ORDER.STATUS.in(statusList));
        Order order = orderMapper.selectOneByQuery(qw);
        if (order==null){
            throw new BadRequestException("此订单暂时无法删除");
        }
        Db.tx(()->{
            //删除订单
            orderMapper.deleteById(orderId);
            //删除订单关联数据
            relationMapper.deleteByQuery(QueryWrapper.create().where(ORDER_CART_RELATION.ORDER_ID.eq(orderId)));
            return true;
        });
    }

    /**
     * 通过订单号查询订单信息
     * @param orderNo 订单号
     * @return 返回订单
     */
    public Order selectByNo(String orderNo) {
        QueryWrapper qw = QueryWrapper.create().where(ORDER.ORDER_NO.eq(orderNo));
        Order order = orderMapper.selectOneByQuery(qw);
        return order;
    }

    /**
     * 通过订单号查询订单记录
     * @param orderNo 订单号
     * @return 返回订单记录
     */
    public OrderBill selectBillByNo(String orderNo) {
        QueryWrapper qw = QueryWrapper.create().where(ORDER_BILL.ORDER_NO.eq(orderNo));
        OrderBill bill = orderBillMapper.selectOneByQuery(qw);
        return bill;
    }

    /**
     * 同时更新订单状态和订单信息数据
     * @param orderNo 订单号
     * @param status 状态
     */
    public void updateOrderStatus(String orderNo, Integer status) {
        Order order = selectByNo(orderNo);
        OrderBill orderBill = selectBillByNo(orderNo);
        Db.tx(() -> {
            if (order != null) {
                order.setStatus(status);
                orderMapper.update(order);
            }
            if (orderBill != null) {
                orderBill.setStatus(status);
                orderBillMapper.update(orderBill);
            }
            return true;
        });
    }

    /**
     * 出餐逻辑
     * @param orderNo 订单号
     */
    public void served(String orderNo) {
        //查询订单
        Order order = selectByNo(orderNo);
        if (order==null){
            throw new OrderException("该订单不存在");
        }
        //判断订单状态
        if (order.getStatus().compareTo(OrderEnum.ORDER_STATUS_NO_SERVE.getIntValue())!=0){
            throw new OrderException("该订单暂时无法进行出餐");
        }
        //修改订单状态
        updateOrderStatus(orderNo,OrderEnum.ORDER_STATUS_SERVED.getIntValue());
    }

    /**
     * 完成订单逻辑
     * @param orderNo 订单号
     */
    public void finished(String orderNo) {
        //查询订单
        Order order = selectByNo(orderNo);
        //判断订单状态
        if (order.getStatus().compareTo(OrderEnum.ORDER_STATUS_SERVED.getIntValue())!=0){
            throw new OrderException("该订单暂时无法进行出餐");
        }
        Db.tx(()->{
            //修改订单状态
            updateOrderStatus(orderNo,OrderEnum.ORDER_STATUS_FINISHED.getIntValue());
            //扣除餐桌人数
            DiningTable table = tableMapper.selectOneById(order.getTableId());
            Integer usedQuantity = table.getUsedQuantity();
            Integer peopleQuantity = order.getPeopleQuantity();
            table.setUsedQuantity(usedQuantity-peopleQuantity);
            tableMapper.update(table);
            return true;
        });
    }

    /**
     * 取消订单
     * @param orderNo 订单号
     */
    public void cancel(String orderNo) {
        Order order = selectByNo(orderNo);
        //判断订单状态
        if (OrderEnum.ORDER_STATUS_NO_PAY.getIntValue().compareTo(order.getStatus())!=0){
            throw new BadRequestException("该订单无法取消");
        }
        Db.tx(()->{
            //删除订单
            orderMapper.deleteById(order.getId());
            //删除关联订单
            relationMapper.deleteByQuery(QueryWrapper.create().where(ORDER_CART_RELATION.ORDER_ID.eq(order.getId())));
            //删除缓存中的订单
            RedisUtils.remove(CommonEnum.ORDER_KEY.getValue()+orderNo);
            //释放餐桌资源
            DiningTable table = tableMapper.selectOneById(order.getTableId());
            Integer usedQuantity = table.getUsedQuantity()==null?0:table.getUsedQuantity();
            Integer peopleQuantity = order.getPeopleQuantity() == null ? 0 : order.getPeopleQuantity();
            table.setUsedQuantity(usedQuantity-peopleQuantity);
            tableMapper.update(table);
            return true;
        });
    }

    /**
     * 订单确认
     * @param confirmParam 参数
     * @param userId 用户编号
     */
    public OrderVo confirmOrder(OrderConfirmParam confirmParam, Integer userId) {
        List<CartVo> itemList = confirmParam.getItemList();

        //如果是点击直接购买的，则新建购物车
        if (OrderEnum.CART_TYPE_BUY.getIntValue().equals(confirmParam.getCartType())){
            List<Integer> ids = new ArrayList<>();
            itemList.forEach(cart->{
                Cart cartDB = new Cart();
                BeanUtil.copyProperties(cart,cartDB,"id");
                BigDecimal singlePrice = cartService.getPrice(cart);
                BigDecimal price = singlePrice.multiply(new BigDecimal(cart.getQuantity()));
                cartDB.setPrice(price);
                cartDB.setUserId(userId);
                cartDB.setType(OrderEnum.CART_TYPE_BUY.getIntValue());
                cartDB.setStatus(OrderEnum.CART_STATUS_NO_BUY.getIntValue());
                cartMapper.insertSelective(cartDB);
                ids.add(cartDB.getId());
            });
            //查询新增购物车的数据返回
            RelationManager.addExtraConditionParam("dishStatus",CommonEnum.STATUS_ON.getIntValue());
            RelationManager.addExtraConditionParam("tasteStatus",CommonEnum.STATUS_ON.getIntValue());
            itemList = cartMapper.selectListWithRelationsByQueryAs(QueryWrapper.create().where(CART.ID.in(ids)), CartVo.class);
        }
        //计算订单价格
        OrderPriceDto nowPrice = getNowPrice(itemList);
        OrderVo orderVo = new OrderVo();
        if (ObjectUtil.isNotNull(nowPrice)){
            orderVo.setTotalQuantity(nowPrice.getQuantity());
            orderVo.setTotalPrice(nowPrice.getPrice());
            orderVo.setItemList(itemList);
        }
        //设置单价
        cartService.genUnitPrice(orderVo.getItemList());
        return orderVo;
    }


    /**
     * 通过订单号查询支付单号
     * @param orderNo
     * @return
     */
    public String selectPayNoByOrderNo(String orderNo) {
        PayBill payBill = payBillMapper.selectOneByQuery(QueryWrapper.create().where(PAY_BILL.ORDER_NO.eq(orderNo)));
        if (payBill!=null){
            return payBill.getPayNo();
        }
        return null;
    }
}
